﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Skin2D.Display
{

    interface IDrawCall
    {
        void OnDraw(System.Drawing.Graphics g);
    }

    class DisplayDriver
    {
        #region Singleton
        private static DisplayDriver Insitance;
        public static DisplayDriver Get()
        {
            if (Insitance == null)
                Insitance = new DisplayDriver();
            return Insitance;
        }
        #endregion

        // -------------------------------------------------------------------------- //
        // -------------------------------------------------------------------------- //
        public DisplayDriver()
        {
            m_DrawHandler = new List<IDrawCall>();
        }

        public void Resize(int width, int height)
        {
            m_bitmap = new Bitmap(width, height);
            m_graphic = System.Drawing.Graphics.FromImage(m_bitmap);
            m_graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            m_graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            Width = width;
            Height = height;

        }

        public void Init(int width, int height)
        {
            Resize(width, height);
        }

        public void InitCamera(PictureBox picbox)
        {
            Camera = new Camera(picbox);
        }


        public void Clear()
        {
            m_graphic.Clear(Color.White);
        }

        public void Draw()
        {
            foreach (IDrawCall item in m_DrawHandler)
            {
                item.OnDraw(m_graphic);
            }
        }

        public void AddDrawHandler(IDrawCall obj)
        {
            m_DrawHandler.Add(obj);
        }
        public void RemoveDrawHandler(IDrawCall obj)
        {
            m_DrawHandler.Remove(obj);
        }

        public Bitmap GetImages()
        {
            return m_bitmap;
        }

        public void Save()
        {
            backup = m_graphic.Transform;
        }

        public void Restore()
        {
            m_graphic.Transform = backup;
        }

        public void CameraTransform()
        {
            Matrix current = m_graphic.Transform;
            current.Multiply(Camera.ViewMatrix, MatrixOrder.Append);
            m_graphic.Transform = current;
        }

        public int Width { get; set; }
        public int Height { get; set; }
        public Camera Camera { get; set; }

        private Bitmap m_bitmap;
        private System.Drawing.Graphics m_graphic;
        private List<IDrawCall> m_DrawHandler;

        private Matrix backup;
    }
}
